/*global pi */

pi.mod.define('pi.os.ui', function (pi) {
	"use strict";
	var indexConfirm, indexGetOpenFileNameW, indexCommDlgExtendedError, getOpenFileName, commDlgExtendedError, GetOpenFileNameWStruct, module = {},
		dllPath = "TestDll.dll";

	//The GetOpenFileName function creates an Open dialog box that lets the user specify the drive, directory, and the name of a file or set of files to open.
	//ofnBuf: see getOpenFileNameWStruct
	indexGetOpenFileNameW = 0;
	getOpenFileName = function (ofnBuf) {
		if (!indexGetOpenFileNameW) {
			indexGetOpenFileNameW = pi.vcall.register("comdlg32.dll", "GetOpenFileNameW", pi.vcall.TYPE_BOOL, [pi.vcall.TYPE_POINTER]);
		}
		return pi.vcall.invoke(indexGetOpenFileNameW, ofnBuf);
	};

	// The CommDlgExtendedError function returns a common dialog box error code
	// This code indicates the most recent error to occur during the executionof one of the common dialog box functions.
	//These error codes are defined in Cderr.h.
	indexCommDlgExtendedError = 0;
	commDlgExtendedError = function () {
		if (!indexCommDlgExtendedError) {
			indexCommDlgExtendedError = pi.vcall.register("comdlg32.dll", "CommDlgExtendedError", pi.vcall.TYPE_INT);
		}
		return pi.vcall.invoke(indexCommDlgExtendedError);
	};

	//wrapper for OPENFILENAME Structure, see msdn
	GetOpenFileNameWStruct = function () {
		var self = this;
		self.structSize = 0x58; // TODO
		self.hwndOwner = 0;
		self.hInstance = 0;
		self.strFilter = null;
		self.strCustomFilter = 0;
		self.maxCustFilter = 0;
		self.nFilterIndex = 0;
		self.lpstrFile = 0;
		self.nMaxFile = 0;
		self.lpstrFileTitle = 0;
		self.nMaxFileTitle = 0;
		self.lpstrInitialDir = 0;
		self.lpstrTitle = null;
		self.Flags = 0;
		self.nFileOffset = 0; //word
		self.nFileExtension = 0; //word
		self.lpstrDefExt = 0;
		self.lCustData = 0;
		self.lpfnHook = 0;
		self.lpTemplateName = 0;
		self.pvReserved = 0;
		self.dwReserved = 0;
		self.FlagsEx = 0;

		self.GetBuffer = function () {
			var buf, strBufSize, strBB;
			buf = pi.jsByteBuffer(self.structSize, 0, 0xcc);
			//计算所有字符串需要的buffer大小,注意计算'\0'(+3 strings)
			//因为扩容后会导致之写入的buffer地址失效,因此要在写入所有字符串之前计算大小
			strBufSize = (self.strFilter.length + self.lpstrInitialDir.length + self.lpstrTitle.length + 3) * 2;
			strBB = pi.jsByteBuffer(strBufSize, 0, 0xcc);

			//依次将所有的字段写入buffer,注意每个字段的大小(注意与.h文件核对)
			buf.wi(self.structSize);
			buf.wi(self.hwndOwner);
			buf.wi(self.hInstance);

			//在写入数据之前记录当前buffer的offset.下同
			buf.writeBufferPointer(strBB.buf, strBB.wOffset);
			strBB.ws(self.strFilter);

			buf.wi(self.strCustomFilter);
			buf.wi(self.maxCustFilter);
			buf.wi(self.nFilterIndex);
			buf.writeBufferPointer(self.lpstrFile);
			buf.wi(self.nMaxFile);
			buf.wi(self.lpstrFileTitle);
			buf.wi(self.nMaxFileTitle);

			buf.writeBufferPointer(strBB.buf, strBB.wOffset);
			strBB.ws(self.lpstrInitialDir);

			buf.writeBufferPointer(strBB.buf, strBB.wOffset);
			strBB.ws(self.lpstrTitle);

			buf.wi(self.Flags);
			buf.wsh(self.nFileOffset); //word
			buf.wsh(self.nFileExtension); //word
			buf.wi(self.lpstrDefExt);
			buf.wi(self.lCustData);
			buf.wi(self.lpfnHook);
			buf.wi(self.lpTemplateName);
			buf.wi(self.pvReserved);
			buf.wi(self.dwReserved);
			buf.wi(self.FlagsEx);

			return buf.buf;
		};
	};

	/*
	 * 确认框
	 */
	indexConfirm = 0;
	module.confirmBox = function (msg) {
		if (!indexConfirm) {
			indexConfirm = pi.vcall.register(dllPath, "Confirm", pi.vcall.TYPE_BOOL, [pi.vcall.TYPE_STRING]);
		}
		return pi.vcall.invoke(indexConfirm, msg);
	};

	/*
	 * open file dialog wrapper.
	 * multiSel: 允许多选?
	 * filter:　过滤字符串，用\0分隔,并以\0结尾, eg:"All\0*.*\0text\0*.txt\0js\0*.js\0"
	 * initDir: 初始路径
	 * [buffSize]: 用以接收路径的缓冲区大小(字符数),默认为4000
	 */
	module.openFileDialog = function (multiSel, filter, initDir, title, bufferSize) {
		var self = this;
		self.multiSel = multiSel;
		self.filter = filter;
		self.initDir = initDir;
		self.title = title;

		self.ofn = new GetOpenFileNameWStruct();
		if (multiSel) {
			self.ofn.Flags = 0x00081a00; //OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_EXPLORER;
		} else {
			self.ofn.Flags = 0x00081800; //OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;
		}
		self.ofn.strFilter = filter;
		self.ofn.lpstrInitialDir = initDir; // + "\\"; //必须以'\'结尾
		self.ofn.lpstrTitle = title;

		bufferSize = pi.util.DV(bufferSize, 4000); //最多容纳的字符数
		self.ofn.lpstrFile = pi.lang.createArrayBuffer(bufferSize * 2);
		self.ofn.nMaxFile = bufferSize;

		//显示dialog
		self.show = function () {
			var param = self.ofn.GetBuffer();
			return getOpenFileName(param);
		};

		//获取文件路径string
		self.getFile = function () {
			var r, files;
			r = null;
			files = self.getFiles();
			if (files.length >= 1) {
				r = files[0];
			}
			return r;
		};

		//获取文件路径数组
		self.getFiles = function () {
			var r, i, s, bb, arr, root, index, tempArr = [];
			bb = pi.jsByteBuffer();
			bb.buf = self.ofn.lpstrFile; //获取结果
			//直到读到空字符串为止.
			//当选择一个文件时,第一个字符串就为full path;
			//当多选时,第一个字符串为dir, 以后每个字符串为name
			index = 0;
			while ((s = bb.rs()) !== "") {
				tempArr[index++] = s;
			}

			if (tempArr.length <= 1) {
				r = tempArr;
			} else {
				arr = [];
				root = tempArr[0];
				for (i = 1; i < tempArr.length; i += 1) {
					arr[i - 1] = root + "\\" + tempArr[i];
				}
				r = arr;
			}
			return r;
		};
	};
	return module;
});